<?php
/**
 * Game_MapData
 *
 * Класс Game_MapData отвечает за обработку данных, свзяанных с картой
 *
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @version 1.0
 */
class Game_MapData {
  
	private static $_minMapCoord_1 = -200;
	private static  $_minMapCoord_2 = -200;
	private static  $_maxMapCoord_1 = 200;
	private static  $_maxMapCoord_2 = 200;
	private static  $_radiusOfWaveSettling = 3; //- шаг ширины радиуса диска текущего заселения. Например, при шаге 3 и определенной заселенности очередная волна может идти в радиусе от 9 до 12 клеток от центра.
	private static  $_minimumRadiusOfWaveSettling = 10; // Минимальный радиус от центра для заселения
	private static  $_percentageToSettle = 20; // Процент заселяемых ячеек

	/**
	 * Инициализация карты на всю игру
	 */
	public static function initAllGameMap() {
		$objDB = Service_Database::instance();
		$arrZones = array();
		$objDB->query("SET foreign_key_checks = 0;");
		$objDB->query("TRUNCATE `map_data`;");
		$objDB->query("TRUNCATE `map_zone`;");
		for ($x = self::$_minMapCoord_1; $x < self::$_maxMapCoord_1; $x++) {
			$stmt = '';
			for ($y = self::$_minMapCoord_2; $y < self::$_maxMapCoord_2; $y++) {
				if (!empty($stmt)) $stmt.= ', ';
				$zone = self::_getMapZone($x, $y);
				$arrZones[$zone] = (empty($arrZones[$zone]) ? 1 : ($arrZones[$zone] + 1));
				$stmt .= "(" . $x . ", " . $y . ", " . $zone . ")";
				
			}
			$stmt = "INSERT INTO `map_data`	(`coord_1`, `coord_2`, `zone`) VALUES " . $stmt;
			$objDB->query($stmt);
		}
		$stmt = '';
		foreach ($arrZones as $zoneId => $amount) {
			if (!empty($stmt)) $stmt.= ', ';
			$stmt .= "(" . $zoneId . ", " . $amount . ", " . intval($amount *  self::$_radiusOfWaveSettling / 100) . ", 0)";
		}
		$stmt = "INSERT INTO `map_zone`	(`zone`, `cells_amount`, `cells_to_settle`, `were_settled`) VALUES " . $stmt;
		$objDB->query($stmt);
		
		self::_initAllGameMapByPlaces();
		$objDB->query("SET foreign_key_checks = 1;");
	}
	
	/**
	 * Заселить место. Выбирает свободные координаты на карте и заселяет
	 * 
	 * @param int $placeId
	 */
	public static function settleNewPlace($placeId) {
		$objDB = Service_Database::instance();
		// Определяем, по каким координатам производить заселение
		$stmt = "SELECT `zone`
				FROM `map_zone`
				WHERE `cells_to_settle` > `were_settled` AND `zone` > 0 
				ORDER BY `zone` ASC
				LIMIT 1
		";
		$mapZone = $objDB->selectSimpleField($stmt);
		$stmt = "SELECT * 
				FROM `map_data`
				WHERE 
					`zone` = " . $mapZone . " 
					AND `cell_type` = 0
		";
		$arrMapCells = $objDB->select($stmt);
		$arrMapCell = $arrMapCells[rand(0, sizeof($arrMapCells) - 1)];
		
		// Задаем координаты для нового места
		$stmt = "UPDATE `place` SET `coord_1` =" . $arrMapCell['coord_1'] . ", `coord_2` = " . $arrMapCell['coord_2'] . " WHERE `ID_place` = " . $placeId . "";
		$objDB->query($stmt);
		
		// Записываем, что ячейка занята и инкрементируем занятость зоны
		self::_updateMapDataAfterSettling($arrMapCell['coord_1'], $arrMapCell['coord_2']);
		$zone = self::_getMapZone($arrMapCell['coord_1'], $arrMapCell['coord_2']);
		self::_incrementMapZoneWereSettled($zone);
	}
	
	/**
	 * Заполняет данные карты информацией о деревнях
	 */
	private static function  _initAllGameMapByPlaces() {
		$objGamePlace = new Game_Place();
		$arrPlaces = $objGamePlace->find('all');
		foreach ($arrPlaces as $arrPlace) {
			self::_updateMapDataAfterSettling($arrPlace['coord_1'], $arrPlace['coord_2']);
			$zone = self::_getMapZone($arrPlace['coord_1'], $arrPlace['coord_2']);
			self::_incrementMapZoneWereSettled($zone);
		}
	}
	
	/**
	 * Обновляет данные карты, после заселения деревни
	 * 
	 * @param int $coord1
	 * @param int $coord2
	 */
	private static function _updateMapDataAfterSettling($coord1, $coord2) {
		$objDB = Service_Database::instance();
		$stmt = "UPDATE `map_data` SET `cell_type` = 1 WHERE `coord_1` = " . $coord1 . " AND  `coord_2` = " . $coord2 . "";
		$objDB->query($stmt);
	}	
	
	/**
	 * Увеличивает счетчик заселения в соответсвующей зоне карты
	 * 
	 * @param int $zone
	 */
	private static function _incrementMapZoneWereSettled($zone) {
		$objDB = Service_Database::instance();
		$stmt = "UPDATE `map_zone` SET `were_settled` = `were_settled` + 1 WHERE `zone` = " . $zone . "";
		$objDB->query($stmt);
	}
	
	/**
	 * Получает номер зоны по координатам
	 * 
	 * @param int $coord1
	 * @param int $coord2
	 */
	private static function _getMapZone($coord1, $coord2) {
		$cellRadius = sqrt($coord1 * $coord1 + $coord2 * $coord2);
		$zone = 0;
		if ($cellRadius >= self::$_minimumRadiusOfWaveSettling) {
			$zone = 1 + intval(($cellRadius - self::$_minimumRadiusOfWaveSettling) / self::$_radiusOfWaveSettling);
		}
		return $zone;
	} 
}
?>